package host.springboot.framework.jwt.storage;

import com.alibaba.ttl.TransmittableThreadLocal;
import host.springboot.framework.core.enumeration.error.ErrorCodeEnum;
import host.springboot.framework.core.exception.ApplicationException;
import host.springboot.framework.jwt.payload.JwtPayload;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.Objects;
import java.util.Optional;

/**
 * 当前用户上下文存储
 *
 * @author JiYinchuan
 * @since 1.0.0
 */
public class JwtPayloadStorage {

    private static final ThreadLocal<JwtPayload> LOCAL = new TransmittableThreadLocal<>();

    /**
     * 设置用户JWT信息
     *
     * @param payload JWT载荷
     * @return JwtPayload
     * @since 1.0.0
     */
    public static JwtPayload set(final JwtPayload payload) {
        LOCAL.set(payload);
        return payload;
    }

    /**
     * 获取用户JWT信息
     *
     * @return JwtPayload
     * @since 1.0.0
     */
    public static @Nullable JwtPayload get() {
        return LOCAL.get();
    }

    /**
     * 获取用户JWT信息
     *
     * @return JwtPayload
     * @since 1.0.0
     */
    public static @NonNull Optional<@Nullable JwtPayload> getOpt() {
        return Optional.ofNullable(get());
    }

    /**
     * 获取用户JWT信息
     *
     * @return JwtPayload
     * @throws ApplicationException 未获取到用户JWT信息
     * @since 1.0.0
     */
    public static @NonNull JwtPayload getThrow() throws ApplicationException {
        Optional<JwtPayload> jwtPayload = Optional.ofNullable(get());
        if (jwtPayload.isPresent()) {
            return jwtPayload.get();
        }
        throw new ApplicationException(ErrorCodeEnum.ACCESS_PERMISSION_ERROR);
    }

    /**
     * 判断是否已经存在用户JWT信息
     *
     * @return {false: 不存在, true: 已存在}
     * @since 1.0.0
     */
    public static boolean isExists() {
        return Objects.nonNull(get());
    }

    /**
     * 移除用户JWT信息
     *
     * @since 1.0.0
     */
    public static void remove() {
        LOCAL.remove();
    }
}
